package core;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedList;

import javax.swing.JOptionPane;

import dbms.DBAddingFunctions;
import dbms.DBGeneralFunctions;
import dbms.DBParameters;
import dbms.DBSelectingFunctions;
import filemanager.FileManager;
import graphic.MainFrame;

public class Function {

	public static boolean serverLogin(String userId, String password)
	{
		if(!DBGeneralFunctions.serverLogin(userId, password)) return false;
		return true;
	}
	
	public static boolean clientLogin(String userId, String password)
	{
		if(Server.getInstance().getUsers().get(userId) != null) return false;
		if(!DBGeneralFunctions.clientLogin(userId, password)) return false;
		return true;
	}
	
	public static synchronized boolean addUser(String userId, String password)
	{
		if(!DBAddingFunctions.addUser(userId, password)) return false;
		return true;
	}
	
	public static synchronized boolean removeUser(String userId)
	{
		if(!DBAddingFunctions.removeUser(userId)) return false;
		return true;
	}
	
	public static synchronized boolean addProgram(String programName, String extenzion, String template)
	{
		if(!DBAddingFunctions.addProgram(programName, extenzion)) return false;
		
		FileManager newProgramFileManager = new FileManager(programName, extenzion);
		if(!newProgramFileManager.createStructure(template))
		{
			DBAddingFunctions.removeProgram(programName);
			return false;
		}
		
		Server.getInstance().programs.put(programName, newProgramFileManager);
		
		return true;
	}
	
	public static synchronized boolean removeProgram(Server server, String programName)
	{
		FileManager programFileManager = server.programs.get(programName);
		if(programFileManager == null) return false;
		
		if(!DBAddingFunctions.removeProgram(programName)) return false;
		
		if(!programFileManager.removeStructure())
		{
			MainFrame.getInstance().showMessage("Error while deleting the directories related to the program./nPlease delete them manually.", JOptionPane.ERROR_MESSAGE);
			return false;
		}
		
		server.programs.remove(programName);
		
		return true;
	}

	public static synchronized boolean addProgramToUser(String programName, String userId)
	{
		if(!DBAddingFunctions.addProgramToUser(userId, programName)) return false;
		
		LoggedUserThread loggedUser = Server.getInstance().getUsers().get(userId);
		if(loggedUser != null)
			loggedUser.initLoggedUser();
		
		return true;
	}
	
	public static synchronized boolean addNewFile(String fileName, String programName)
	{
		FileManager fileManager = Server.getInstance().getPrograms().get(programName);
		if(fileManager == null) return false;		
		
		// TODO: potrebbe essere creato il file nel DB e non nella cartella
		if(DBAddingFunctions.addNewFile(fileName, programName))
			if(fileManager.newFile(fileName))
			{
				Server.getInstance().reInitAssociatedUsers(programName);
										
				return true;
	
			} else DBAddingFunctions.removeFile(fileName, programName);
		
		return false;
	}

	public static synchronized boolean removeFile(String fileName, String programName)
	{
		FileManager fileManager = Server.getInstance().getPrograms().get(programName);
		if(fileManager == null) return false;

		// TODO: potrebbe essere eliminato il file e non eliminato dal DB
		if(fileManager.removeFile(fileName))
			if(DBAddingFunctions.removeFile(fileName, programName))
				return true;
		
		return false;
	}
	
	public static synchronized boolean addRelease(int fileId, String fileName, int releaseNumber, String releaseNote, String userId, String programName)
	{
		FileManager fileManager = Server.getInstance().getPrograms().get(programName);
		if(fileManager == null) return false;
		
		// TODO: potrebbe essere aggiunto il file e non aggiunto nel DB
		try {
			if(fileManager.addNewRelease(fileName, releaseNumber))
				if((DBAddingFunctions.addRelease(fileId, userId, releaseNumber, releaseNote)) &&
						(DBAddingFunctions.setFileLastRelease(fileId, releaseNumber)) &&
						(DBAddingFunctions.setFileLastCommitter(fileId, userId)))
				{
					Server.getInstance().reInitAssociatedUsers(programName);
					return true;
				}
			} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		
		return false;
	}
	
	public static boolean changeProgramName(String programName, String newName)
	{
		if(DBAddingFunctions.changeProgramName(programName, newName))
			return true;
		
		return false;
	}
	
	
	public static boolean setProgramParameter(String programName, String parameter, Object value)
	{
		if(DBAddingFunctions.setProgramParameter(programName, parameter, value))
			return true;
		
		return false;
	}
	
	public static LinkedList<String> getUserNamesList()
	{
		try {
			LinkedList<String> users = new LinkedList<String>();
			
			ResultSet ris = DBSelectingFunctions.getUsers();
			while(ris.next())
				users.add(ris.getString("userid"));
			
			return users;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	
	public static LinkedList<String> getFileNamesList(String programName)
	{
		try {
			LinkedList<String> files = new LinkedList<String>();
			
			ResultSet ris = DBSelectingFunctions.getFiles(programName);
			while(ris.next())
				files.add(ris.getString("name"));
			
			return files;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	public static LinkedList<String> getProgramNamesList()
	{
		try {
			LinkedList<String> files = new LinkedList<String>();
			
			ResultSet ris = DBSelectingFunctions.getPrograms();
			while(ris.next())
				files.add(ris.getString("name"));
			
			return files;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	
	public static HashMap<String, String> getProgramParameterMap(String programName)
	{		
		try {
			HashMap<String, String> programParameter = new HashMap<String, String>();

			ResultSet ris = DBSelectingFunctions.getProgramParameter(programName);
			
			if(!ris.next()) return null;
			
			programParameter.put(DBParameters.EXTENZION, ris.getString(DBParameters.EXTENZION));
			programParameter.put(DBParameters.NEW_FILE, ris.getString(DBParameters.NEW_FILE));

			return programParameter;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
}